package com.rtx.edi.gatway.handle.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.management.RuntimeErrorException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rtx.api.utils.MultipleDataSource;
import com.rtx.common.EdiConstant;
import com.rtx.common.EdiSqlBuilder;
import com.rtx.edi.gatway.cache.EdiApiContext;
import com.rtx.edi.gatway.cache.EdiApiDataContext;
import com.rtx.edi.gatway.cache.EdiColumnValue;
import com.rtx.edi.gatway.dao.GatWayHandleDAO;
import com.rtx.edi.gatway.handle.GatWayHandle;
import com.rtx.edi.gatway.listener.EdiListener;
import com.rtx.edi.platform.custom.bean.EdiCustomProcess;
import com.rtx.edi.platform.custom.mapper.EdiCustomProcessMapper;
import com.rtx.edi.platform.ediapi.bean.EdiApi;
import com.rtx.edi.platform.ediapi.mapper.EdiApiMapper;
import com.rtx.edi.platform.rule.bean.PlSerialRule;
import com.rtx.edi.platform.rule.bean.UpdRule;
import com.rtx.edi.platform.rule.bean.WhseidRule;
import com.rtx.edi.platform.rule.mapper.UpdRuleMapper;
import com.rtx.edi.platform.rule.mapper.WhseidRuleMapper;
import com.rtx.edi.platform.rule.service.PlSerialRuleService;
import com.rtx.edi.platform.structure.mapper.PlApiMappingStructureMapper;
import com.rtx.edi.platform.tableconfig.bean.EdiColumnValueConfig;
import com.rtx.edi.platform.tableconfig.bean.EdiTableConfig;
import com.rtx.edi.platform.tableconfig.mapper.EdiColumnValueConfigMapper;
import com.rtx.edi.platform.tableconfig.mapper.EdiTableConfigMapper;
import com.rtx.wms.std.common.mapper.CommonMapper;

import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

@Primary
@Component
public class GatWayHandleDefaultImpl extends GatWayHandle{
	
//	@Autowired
//	PlApiMappingMapper plApiMappingMapper;
//	
//	@Autowired
//	PlApibaseinfoMapper plApibaseinfoMapper;
	
	@Autowired
	EdiApiMapper ediApiMapper;
	
	@Autowired
	EdiCustomProcessMapper ediCustomProcessMapper;
	
	@Autowired
	PlApiMappingStructureMapper plApiMappingStructureMapper;
	
	@Autowired
	EdiTableConfigMapper ediTableConfigMapper;
	
	@Autowired
	EdiColumnValueConfigMapper ediColumnValueConfigMapper;
	
	@Autowired
	WhseidRuleMapper whseidRuleMapper;
	
	@Autowired
	UpdRuleMapper updRuleMapper;
	
	@Autowired
	GatWayHandleDAO gatWayHandleDAO;
	
	@Autowired
	CommonMapper commonMapper;
	
	@Autowired
	PlSerialRuleService plSerialRuleService;
	
    @Value("${wms.app.sysnumberrule.url}")
    private String sysnumberrule_url;
	
	
	Logger logger = LoggerFactory.getLogger(this.getClass());
	

	@Override
	protected void convertTargetRequest(EdiApiDataContext dataContext) {
		dataContext.setTargetRequest(JSONUtil.parseObj(dataContext.getSourceRequestStr()));
	}


	@Override
	protected void executerLoadValidate(EdiApiDataContext apiContext) {
		
		try {
			List<EdiListener> validateList = apiContext.getApiContext().getCustomValidate();
			apiContext.getEdiLog().getEdiContentLog().setExecuterloadvalidatepre(JSON.toJSONString(validateList));
			
			if(CollectionUtils.isEmpty(validateList)) {
				apiContext.getEdiLog().getEdiContentLog().setExecuterloadvalidateafter("自定义校验逻辑为空-无需执行");
				return;
			}
			
			StringBuffer errorMsg = new StringBuffer();
			boolean errorflag = false;
			
			for(EdiListener validate:validateList) {
				try {
					validate.doCustom(apiContext);
				} catch (Exception e) {
					errorflag = true;
					errorMsg.append(e.getMessage());
				}
			}
			
			if(errorflag) {
				throw new RuntimeException(errorMsg.toString());
			}
			
		} catch (Exception e) {
			apiContext.getEdiLog().getEdiContentLog().setExecuterloadvalidateafter("执行自定义校验未通过-"+e.getMessage());
			logger.error("执行自定义校验未通过-",e.getMessage());
		}

	}

	@Override
	protected void buildTableValueObject(EdiApiDataContext dataContext) {
		List<EdiTableConfig> ediTableConfigList = dataContext.getApiContext().getEdiTableConfigList();
		
		
		for(EdiTableConfig config:ediTableConfigList) {
			
			
			if(EdiConstant.REQUEST_ROOT_NODE.equals(config.getRequestrootnode().toUpperCase())) {
				//映射主表信息
				List<EdiColumnValue> mainEdiColumnValue = new ArrayList<>();
				
				for(EdiColumnValueConfig valueConfig:config.getColumnvalue()) {
					
					EdiColumnValue columnValue = buildColumnValue(dataContext,0,dataContext.getTargetRequest(),config,valueConfig);
					
					mainEdiColumnValue.add(columnValue);
					
					dataContext.setMainTable(mainEdiColumnValue);
				}
				
				dataContext.getEdiLog().getEdiContentLog().setBuildtablevalueaftermain(JSON.toJSONString(mainEdiColumnValue));
			}else {
				Map<String,Map<Integer,List<EdiColumnValue>>> subtableMap = null;
				if(dataContext.getSubtableMap() == null) {
					subtableMap = new HashMap<String, Map<Integer,List<EdiColumnValue>>>();
					dataContext.setSubtableMap(subtableMap);
				}

				String subRootNode = dataContext.getTargetRequest().getByPath(config.getRequestrootnode()).toString();

				if(!subRootNode.startsWith("[")) {
					continue;
				}

				Map<Integer,List<EdiColumnValue>> subTableMap = new HashMap<Integer, List<EdiColumnValue>>();
				JSONArray subRootNodeArray = JSONUtil.parseArray(subRootNode);
				for(int i=1;i<=subRootNodeArray.size();i++) {
					Integer index = i;
					List<EdiColumnValue> subEdiColumnValueList = new ArrayList<EdiColumnValue>();
					for(EdiColumnValueConfig valueConfig:config.getColumnvalue()) {

						EdiColumnValue columnValue = buildColumnValue(dataContext,i,dataContext.getTargetRequest(),config,valueConfig);

						subEdiColumnValueList.add(columnValue);
					}
					subTableMap.put(index, subEdiColumnValueList);
				}

				subtableMap.put(config.getName(), subTableMap);
				
				dataContext.getEdiLog().getEdiContentLog().setBuildtablevalueaftersub(JSON.toJSONString(subtableMap));
			}
		}
		
		
	}
	
	//生成字段与值对象
	protected EdiColumnValue buildColumnValue(EdiApiDataContext dataContext,int index,JSONObject rootNode,EdiTableConfig config,EdiColumnValueConfig valueConfig) {
		EdiColumnValue mainColumnValue = new EdiColumnValue();
		mainColumnValue.setTablename(config.getName());
		mainColumnValue.setColumnname(valueConfig.getColumnname());
		mainColumnValue.setSkipinsert(valueConfig.getSkipinsert());
		mainColumnValue.setSkipupdate(config.getSkipupdate());
		mainColumnValue.setUpdRule(config.getUpdRule());
		mainColumnValue.setIslinenumber(valueConfig.getIslinenumber());
		mainColumnValue.setIsseriakey(valueConfig.getIsseriakey());
		
		////目标字段值的路径
		String path = "";
		if(index == 0) {
			//主表填充
			path = Optional.ofNullable(valueConfig.getRequestvaluepath()).orElse("").replace("root.","") ;
		}else {
			//从表填充
			String tempPath =  Optional.ofNullable(valueConfig.getRequestvaluepath()).orElse("").replace("root.","") ;
			path = tempPath.replace("数组", "["+(index-1)+"]");
		}

		Object value = "";
		if(StringUtils.hasLength(path)) {
			//目标字段路径对应的值
			value = rootNode.getByPath(path);
		}else {
			value = "";
		}

		
		//处理目标字段值的值转换
		value = handleConvertrule(dataContext,valueConfig,value);

		//处理目序列号
		value = handleSeriakeyrule(dataContext,valueConfig,value);
		
		//处理目标值默认方法生成  UUID 或者其它的
		value = handleDefaultValue(dataContext,valueConfig,value);
		
		//处理目标值为行号
		value = handleLinenumber(dataContext,valueConfig,value,index);
		
		//处理目标值为仓库号
		value = handleWhseid(dataContext,valueConfig,value,index);
		
		//设置值
		mainColumnValue.setValue(value);
		
		//设置字段值类型
		Class type = handleValueType(valueConfig,value);
		mainColumnValue.setValueType(type);
		
		mainColumnValue.setUpdColumn(valueConfig.getUpdcolumn());
		mainColumnValue.setUpdCondition(valueConfig.getUpdcondition());
		
		return mainColumnValue;
	}
	
	//处理目标字段值的值转换
	protected Object handleConvertrule(EdiApiDataContext dataContext,EdiColumnValueConfig valueConfig,Object oriValue) {
		return oriValue;
	}
	
	//设置wms流水号
	protected Object handleSeriakeyrule(EdiApiDataContext dataContext,EdiColumnValueConfig valueConfig,Object oriValue) {
		if("true".equals(valueConfig.getIsseriakey())) {
			String wmskey =  dataContext.getApiGlobalMap().get(EdiConstant.WMS_KEY)+"";
			if(StringUtils.hasLength(wmskey)) {
				return wmskey;
			}else {
				throw new RuntimeException("字段"+valueConfig.getColumnname()+"获取WMS流水号失败");
			}
		}
		return oriValue;
	}
	
	//处理目标值默认方法生成  UUID 或者其它的
	protected Object handleDefaultValue(EdiApiDataContext dataContext,EdiColumnValueConfig valueConfig,Object oriValue) {
		if("true".equals(valueConfig.getIsuuid())) {
			String apiuid =  dataContext.getApiGlobalMap().get(EdiConstant.API_UID)+"";
			if(StringUtils.hasLength(apiuid)) {
				return apiuid;
			}else {
				throw new RuntimeException("字段"+valueConfig.getColumnname()+"获取WMS流水号失败");
			}
		}
//		
//		//返回强制覆盖值
//		if(StringUtils.hasLength(valueConfig.getOverridevalue())) {
//			return valueConfig.getOverridevalue();
//		}
		
		//返回默认值
		if(StringUtils.hasLength(valueConfig.getDefaultvalue())) {
			if(null == oriValue) {
				return valueConfig.getDefaultvalue();
			}
		}
		return oriValue;
	}
	
	//处理目标值的行号
	protected Object handleLinenumber(EdiApiDataContext dataContext,EdiColumnValueConfig valueConfig,Object oriValue,Integer index) {
		if("true".equals(valueConfig.getIslinenumber())) {
			String linenumber =  String.format("%05d", index)+"";
			return linenumber;
		}
		return oriValue;
	}
	
	//处理目标值的行号
	protected Object handleWhseid(EdiApiDataContext dataContext,EdiColumnValueConfig valueConfig,Object oriValue,Integer index) {
		if("true".equals(valueConfig.getIswhseid())) {
			return dataContext.getApiGlobalMap().get(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY);
		}
		return oriValue;
	}
	
	//判断字段值类型
	protected Class handleValueType(EdiColumnValueConfig valueConfig,Object oriValue) {
		Class type = null;
		if(oriValue!=null) {
			type = oriValue.getClass();
		}
		return type;
	}

//	@Override
//	protected void fillTableValueByConfig(EdiApiDataContext apiContext) {
//
//		
//	}

	@Override
	protected void executerPreSaveCustom(EdiApiDataContext apiContext) {
		
		StringBuffer errorMsg = new StringBuffer();
		boolean errorflag = false;
		
		List<EdiListener> validateList = apiContext.getApiContext().getCustomValidate();
		apiContext.getEdiLog().getEdiContentLog().setExecuterloadvalidatepre(JSON.toJSONString(validateList));
		
		if(CollectionUtils.isEmpty(validateList)) {
			apiContext.getEdiLog().getEdiContentLog().setExecuterloadvalidateafter("自定义校验逻辑为空-无需执行");
			return;
		}
		
		List<EdiListener> preHandleList = apiContext.getApiContext().getCustomPreHandle();
		for(EdiListener validate:preHandleList) {
			try {
				validate.doCustom(apiContext);
			} catch (Exception e) {
				errorflag = true;
				errorMsg.append(e.getMessage());
			}
		}
		
		if(errorflag) {
			apiContext.getEdiLog().getEdiContentLog().setExecuterloadvalidateafter("执行插入前自定义逻辑异常-"+errorMsg.toString());
			throw new RuntimeException(errorMsg.toString());
		}

	}

	@Override
	protected void executerAfterSaveCustom(EdiApiDataContext apiContext) {
		List<EdiListener> afterHandle = apiContext.getApiContext().getCustomAfterHandle();
		for(EdiListener validate:afterHandle) {
			validate.doCustom(apiContext);
		}
	}

	/**
	 * 通过配置编码从数据库查找信息
	 */
	@Override
	protected void loadConfigFromDatabase(String configCode, EdiApiContext apiContext) {
		LambdaQueryWrapper<EdiApi> mappingQuery = Wrappers.lambdaQuery();
		mappingQuery.eq(EdiApi::getCode, configCode);
		List<EdiApi> ediapiList = ediApiMapper.selectList(mappingQuery);

		//对接场景编码不存在直接报错
		if(CollectionUtils.isEmpty(ediapiList)||ediapiList.size()<1) {
			throw new RuntimeException("configCode-"+configCode+"不存在");
		}
		
		EdiApi ediApi = ediapiList.get(0);
		apiContext.setEdiApi(ediApi);
		
		//查询被调用方目标字段与表字段映射
		LambdaQueryWrapper<EdiTableConfig> tableConfigQw = Wrappers.lambdaQuery();
		tableConfigQw.eq(EdiTableConfig::getApiid, ediApi.getId());
		List<EdiTableConfig> tableconfigList = ediTableConfigMapper.selectList(tableConfigQw);
		for(EdiTableConfig tableconfig:tableconfigList) {
			LambdaQueryWrapper<EdiColumnValueConfig> columnValueQW = Wrappers.lambdaQuery();
			columnValueQW.eq(EdiColumnValueConfig::getEditableconfigid, tableconfig.getId());
			List<EdiColumnValueConfig> columnValueList =  ediColumnValueConfigMapper.selectList(columnValueQW);
			tableconfig.setColumnvalue(columnValueList);
			//加载更新规则
			if(StringUtils.hasLength(tableconfig.getUpdaterule())) {
				Long updruleid = Long.parseLong(tableconfig.getUpdaterule());
				UpdRule updRule = updRuleMapper.selectById(updruleid);
				tableconfig.setUpdRule(updRule);
			}
			
		}
		apiContext.setEdiTableConfigList(tableconfigList);
		
		//仓库号确定规则
		Long whseidruleid =Long.parseLong(Optional.ofNullable(ediApi.getWhseidruleid()).orElse("0"));
		WhseidRule  whseidRule  = whseidRuleMapper.selectById(whseidruleid);
		apiContext.setWhseidRule(whseidRule);
		
		//更新规则
		UpdRule updRule = updRuleMapper.selectById(ediApi.getUpdruleid());
		apiContext.setUpdRule(updRule);
		
		//查询所有自定义逻辑
		String customids = ediApi.getCustomids();
		if(StringUtils.hasLength(customids)) {
			List<Long> customis = Arrays.asList(customids.split(",")).stream().map(temp->Long.parseLong(temp)).collect(Collectors.toList());
			List<EdiCustomProcess> ediCustomProcessList = ediCustomProcessMapper.selectBatchIds(customis);
			apiContext.setEdiCustomProcessList(ediCustomProcessList);
		}
		
		//加载流水号规则
		String serialruleid = ediApi.getSerialruleid();
		if(StringUtils.hasLength(serialruleid)) {
			LambdaQueryWrapper<PlSerialRule> serialruleqw = Wrappers.lambdaQuery();
			serialruleqw.eq(PlSerialRule::getId, serialruleid);
			List<PlSerialRule> serialRuleList = plSerialRuleService.list(serialruleqw);
			apiContext.setSerialRule(serialRuleList.get(0));
		}
	}


	@Override
	protected void loadCustom(EdiApiContext apiContext) {
		//加载自定义逻辑
		
		//		查询所有自定义逻辑
		List<EdiCustomProcess> ediCustomProcessList = apiContext.getEdiCustomProcessList();
		
		if(!CollectionUtils.isEmpty(ediCustomProcessList)) {
			//自定义验证集合
			List<EdiListener> customValidateList = new ArrayList<EdiListener>();
			//操作数据库前 自定义逻辑
			List<EdiListener> customPreHandleList = new ArrayList<EdiListener>();
			//操作数据库后 自定义逻辑
			List<EdiListener> customAfterHandleList = new ArrayList<EdiListener>();
			//按照优先级升序排序
			Collections.sort(ediCustomProcessList, (p1, p2) ->p1.getPriority()-p2.getPriority());
			
			for(EdiCustomProcess process:ediCustomProcessList) {

				try {
					if(EdiConstant.CUSTOM_PROCESS_VALIDATE.equals(process.getType())) {
						EdiListener customValidateObject = (EdiListener)context.getBean(process.getBeanname());
						customValidateList.add(customValidateObject);
					}else if(EdiConstant.CUSTOM_PROCESS_PREHANDLE.equals(process.getType())) {
						EdiListener preHandleObject = (EdiListener)context.getBean(process.getBeanname());
						customPreHandleList.add(preHandleObject);
					}else if(EdiConstant.CUSTOM_PROCESS_CUSTOMAFTER.equals(process.getType())) {
						EdiListener customAfterObject = (EdiListener)context.getBean(process.getBeanname());
						customAfterHandleList.add(customAfterObject);
					}
				} catch (Exception e) {
					logger.error("加载自定义类异常",e);
				}


			}
			//加载自定义验证逻辑
			apiContext.setCustomValidate(customValidateList);
			//加载操作数据库后自定义逻辑
			apiContext.setCustomPreHandle(customPreHandleList);
			//加载操作数据库后自定义逻辑
			apiContext.setCustomAfterHandle(customAfterHandleList);
		}

		
		//加载自定义 查找仓库号逻辑
		if(apiContext.getWhseidRule() != null) {
			String beanname =  apiContext.getWhseidRule().getBeanname();
			if(StringUtils.hasLength(beanname)) {
				EdiListener ediListener = (EdiListener) context.getBean(beanname);
				apiContext.setDetermineWhseidHandle(ediListener);
			}
		}
	}


	@Override
	protected void buildApiGlobalMap(EdiApiDataContext apiContext) {
		
		//生成流水号
		PlSerialRule serialRule =	apiContext.getApiContext().getSerialRule();
		apiContext.getEdiLog().getEdiContentLog().setWhseidrulepre(JSON.toJSONString(serialRule));
		
		try {
			String uid = UUID.randomUUID().toString();
			apiContext.getApiGlobalMap().put(EdiConstant.API_UID, uid);
			
			apiContext.getEdiLog().getEdiContentLog().setBuildapiglobalmapafter("生成API_UID-"+uid);
			
			if(serialRule == null) {
				String uidmsg = apiContext.getEdiLog().getEdiContentLog().getBuildapiglobalmapafter();
				apiContext.getEdiLog().getEdiContentLog().setBuildapiglobalmapafter(uidmsg+"-无需生成流水号");
				return;
			}
			
			String wmwhseid = apiContext.getApiGlobalMap().get(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY)+"";
			String wmskey = "";
			if(EdiConstant.SERIAL_RULE_TYPE_RIS_API.equals(serialRule.getType())) {
				wmskey = createwmskeyByAPI(wmwhseid,serialRule.getCode(),serialRule.getRequesturl());
			}else if(EdiConstant.SERIAL_RULE_TYPE_NCOUNT.equals(serialRule.getType())) {
				wmskey = createwmskeyByNcount(wmwhseid,serialRule.getCode(),serialRule.getPrefix()); 
			}else if(EdiConstant.SERIAL_RULE_TYPE_SERIALKEY.equals(serialRule.getType())) {
				wmskey = "";
			}else {
				throw new RuntimeException("生成流水号规则类型-"+serialRule.getType()+"为实现!");
			}
			
			apiContext.getApiGlobalMap().put(EdiConstant.WMS_KEY, wmskey);
			
		} catch (Exception e) {
			logger.error("通过流水号规则-"+serialRule.getName()+"获取流水号异常-",e);
			throw new RuntimeException("通过流水号规则-"+serialRule.getName()+"获取流水号异常-"+e.getMessage());
		}
		

		
	}
	
	private String createwmskeyByNcount(String whseid,String code,String prefix) {
		String keyname = code;
        String wmskey = null;
        Integer count = commonMapper.selectWmskey(keyname);
        if(count == null){
            count = 1;
            commonMapper.insertNcounter(keyname);
        }else{
            commonMapper.updateNcounter(keyname);
        }
        if(StringUtils.hasText(prefix)){
            if(prefix.length() > 2){
                prefix = prefix.substring(0,2);
            }
            wmskey = prefix + String.format("%0" + (10 - prefix.length()) + "d",count);
        }else{
            wmskey = String.format("%010d",count);
        }
        return wmskey;
	}
	
	private String createwmskeyByAPI(String whseid,String code,String baseurl){
		String wmskey = "";
        try {
        	String requesturl = baseurl + whseid.toUpperCase() + "/" + code;
            String body = HttpRequest
                            .get(requesturl)
                            .timeout(30000).execute()
                            .body();
            logger.info("请求地址：{}，获取WMS单号结果：{}",requesturl,body);
            if(StringUtils.hasText(body)){
            	com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(body);
                if("200".equals(jsonObject.getString("returnCode"))){
                	wmskey= jsonObject.getString("data");
                }
            }
        } catch (HttpException e) {
            logger.error("请求地址：{}，获取WMS单号异常：",sysnumberrule_url,e);
        }
		return wmskey;
	}


	@Override
	protected void determineWhseid(EdiApiDataContext dataContext) {
		WhseidRule rule =  dataContext.getApiContext().getWhseidRule();
		
		dataContext.getEdiLog().getEdiContentLog().setWhseidrulepre(JSON.toJSONString(rule));

		
		if(rule == null) {
			dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("确定仓库id规则不能为空!");
			throw new RuntimeException("确定仓库id规则不能为空!");
		}
		
		String type = Optional.ofNullable(rule.getType()).orElse("");
		//类型 defaultvalue 默认仓库 defaultfield 默认字段节点为仓库号 querybyconfig 通过查询获取仓库号 customprocess自定义逻辑
		if("defaultvalue".equals(type)) {
			dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY, rule.getMaindatasource());
			
			dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中获取仓库号-主仓库号-"+rule.getMaindatasource());
			
			if("activewhseid".equals(rule.getSubdatasourcelist())) {
				String wmwhseList = gatWayHandleDAO.selectActiveWhseidNotEnterprise("enterprise");
				
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter(dataContext.getEdiLog().getEdiContentLog().getWhseidruleafter()+"从仓库号-"+wmwhseList);
				dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_SUB_DATASOURCEKEY_LIST, wmwhseList);
			}else {
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter(dataContext.getEdiLog().getEdiContentLog().getWhseidruleafter()+"从仓库号-"+rule.getSubdatasourcelist());
				dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_SUB_DATASOURCEKEY_LIST, rule.getSubdatasourcelist());
			}
		}else if("defaultfield".equals(type)) {
			String path =Optional.ofNullable(rule.getRequestnode()).orElse("").replace("root.", "") ;
			String wmwhseid =  dataContext.getSourceJSONObject().getByPath(path)+"";
			if(!StringUtils.hasLength(wmwhseid)) {
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中配置报文节点路径获取仓库号为空");
				throw new RuntimeException("仓库号获取规则-"+rule.getName()+"-中配置报文节点路径获取仓库号为空");
			}
			if(!wmwhseid.toUpperCase().startsWith("WMWHSE")) {
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中配置报文节点路径获取仓库号不为WMWHSE开头");
				throw new RuntimeException("仓库号获取规则-"+rule.getName()+"-中配置报文节点路径获取仓库号不为WMWHSE开头");
			}
			
			dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中获取仓库号-主仓库号-"+wmwhseid);
			dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY, wmwhseid);
			
			if("activewhseid".equals(rule.getSubdatasourcelist())) {
				String wmwhseList = 	gatWayHandleDAO.selectActiveWhseidNotEnterprise("enterprise");
				dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_SUB_DATASOURCEKEY_LIST, wmwhseList);
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter(dataContext.getEdiLog().getEdiContentLog().getWhseidruleafter()+"从仓库号-"+wmwhseList);
			}else {
				dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_SUB_DATASOURCEKEY_LIST, rule.getSubdatasourcelist());
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter(dataContext.getEdiLog().getEdiContentLog().getWhseidruleafter()+"从仓库号-"+rule.getSubdatasourcelist());
			}
		}else if("querybyconfig".equals(rule.getSubdatasourcelist())) {
			String querysql = rule.getQuerysql();
			List<JSONObject> columnsPath = JSON.parseArray(rule.getQuerycolumns(), JSONObject.class);
			for(JSONObject columnPathConfig:columnsPath) {
				String column = columnPathConfig.getStr("column");
				String path =Optional.ofNullable(columnPathConfig.getStr("path")).orElse("").replace("root.", "") ;
				String vlue =  dataContext.getSourceJSONObject().getByPath(path)+"";
				String queryValue = "'"+vlue+"'";
				String replaceStr = "\\{"+column+"\\}";
				querysql = querysql.replaceAll(replaceStr, queryValue);
			}
			String wmwhseid = gatWayHandleDAO.selectWmseid(rule.getDatasourcekey(), querysql);
			if(StringUtils.hasLength(wmwhseid)) {
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中获取仓库号为空"+"querysql="+querysql);
				throw new RuntimeException("仓库号获取规则-"+rule.getName()+"-中获取仓库号为空");
			}
			if(!wmwhseid.toUpperCase().startsWith("WMWHSE")) {
				dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中获取仓库号不为WMWHSE开头"+"querysql="+querysql);
				
				throw new RuntimeException("仓库号获取规则-"+rule.getName()+"-中获取仓库号不为WMWHSE开头");
			}
			
			dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则-"+rule.getName()+"-中获取仓库号-"+wmwhseid);
			dataContext.getApiGlobalMap().put(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY, wmwhseid);
		}else if("customprocess".equals(type)) {
			if(dataContext.getApiContext().getDetermineWhseidHandle() != null) {
				try {
					dataContext.getApiContext().getDetermineWhseidHandle().doCustom(dataContext);
				} catch (Exception e) {
					logger.error("",e);
					dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("执行自定义仓库号获取规则"+rule.getName()+"-类型-"+"自定义逻辑异常"+e.getMessage());
					throw new RuntimeException("执行自定义仓库号获取规则"+rule.getName()+"-类型-"+"自定义逻辑异常");
				}
			}
		}else {
			dataContext.getEdiLog().getEdiContentLog().setWhseidruleafter("仓库号获取规则"+rule.getName()+"-类型-"+type+"未定义");
			throw new RuntimeException("仓库号获取规则"+rule.getName()+"-类型-"+type+"未定义");
		}
		
	}
	

	@Override
	protected void executerSave(EdiApiDataContext dataContext) {
		String oriDatasourkey = MultipleDataSource.getCurrentDataSourceKey();
		try {
			String datasourcekey =	dataContext.getApiGlobalMap().get(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY)+"";
			MultipleDataSource.setDataSourceKey(datasourcekey);
			
			List<String> sql = EdiSqlBuilder.createInsertSql(dataContext);
			
			gatWayHandleDAO.saveDynamicCreateSql(sql);
			
			MultipleDataSource.ClearDataSourceKey();
			if(null != oriDatasourkey) {
				MultipleDataSource.setDataSourceKey(oriDatasourkey);
			}
		} catch (Exception e) {
			MultipleDataSource.ClearDataSourceKey();
			if(null != oriDatasourkey) {
				MultipleDataSource.setDataSourceKey(oriDatasourkey);
			}
			logger.error("",e);
			throw new RuntimeException("执行插入sql异常"+e.getMessage());
		}
	}
	

	@Override
	protected void executerUpdate(EdiApiDataContext dataContext) {
		String oriDatasourkey = MultipleDataSource.getCurrentDataSourceKey();
		try {
			String datasourcekey =	dataContext.getApiGlobalMap().get(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY)+"";
			MultipleDataSource.setDataSourceKey(datasourcekey);
			
			List<String> sqlList = new ArrayList<String>();
			String mainSql = EdiSqlBuilder.createUpdSqlByColumnValue(dataContext.getMainTable());
			sqlList.add(mainSql);
			gatWayHandleDAO.updDynamicCreateSql(mainSql);
			
			for(String subTableName:dataContext.getSubtableMap().keySet()) {
				Map<Integer,List<EdiColumnValue>> subTableRows = dataContext.getSubtableMap().get(subTableName);
				
				for(Integer index:subTableRows.keySet()) {
					List<EdiColumnValue> subTableRow =  subTableRows.get(index);
					//是否跳过生成更新语句
					if("true".equals(subTableRow.get(0).getSkipupdate())) {
						continue;
					}
					//更新规则为空 则跳过
					UpdRule updRule = subTableRow.get(0).getUpdRule();
					if(updRule == null) {
						continue;
					}
					
					//明细行项更新
					handleDetailUpdRule(updRule,subTableRow,dataContext);
				}
			}
			
			
			
			MultipleDataSource.ClearDataSourceKey();
			if(null != oriDatasourkey) {
				MultipleDataSource.setDataSourceKey(oriDatasourkey);
			}
		} catch (Exception e) {
			MultipleDataSource.ClearDataSourceKey();
			if(null != oriDatasourkey) {
				MultipleDataSource.setDataSourceKey(oriDatasourkey);
			}
			logger.error("",e);
			throw new RuntimeException("执行更新语句异常"+e.getMessage());
		}
	}
	
	private void handleDetailUpdRule(UpdRule updRule,List<EdiColumnValue> detailColumnsValue,EdiApiDataContext dataContext) {
		String existquerycolumns = updRule.getExistquerycolumns();
		//动态组装查询数据sql
		String tempSql = updRule.getExistquerysql();
		existquerycolumns = updRule.getExistquerycolumns();
		for(String columns:existquerycolumns.split(",")) {
			Optional<EdiColumnValue> columnsValue = detailColumnsValue.stream().filter(temp->columns.equals(temp.getColumnname())).findFirst();;
			String value = "";
			if(columnsValue.isPresent()) {
				value = columnsValue.get().getValue()+"";
			}
			
			String queryValue = "'"+value+"'";
			String replaceStr = "\\{"+columns+"\\}";
			tempSql = tempSql.replaceAll(replaceStr, queryValue);

		}
		
		int count = updRuleMapper.queryBySql(tempSql);
		if(count < 1) {
			//允许新增行项
			if("true".equals(updRule.getAllowadddeatil())) {
				//执行新增行项逻辑
				addDetailLine(updRule,detailColumnsValue,dataContext);
			}else {
				throw new RuntimeException("当前数据已经接入wms，当前下发数据存在新增行项，不允许新增！");
			}
		}else if(count > 1){
			throw new RuntimeException("当前数据执行更新规则-"+updRule.getName()+"明细行项查询到多行数据无法进行更新！");
		}else {
			if("true".equals(updRule.getExistcomparethreshold())) {
				//是否根据阀值更新明细行
				StringBuffer statusquerySql = new StringBuffer();
				statusquerySql.append("select "+updRule.getStatuscolumn()+" from "+detailColumnsValue.get(0).getTablename()+" where 1=1");
				
				for(String column:updRule.getStatusquerycolumn().split(",")) {
					Optional<EdiColumnValue> statuscolumn = detailColumnsValue.stream().filter(temp->column.equals(temp.getColumnname())).findFirst();;
					String statuscolumnvalue = "'"+statuscolumn.get().getValue()+"'";
					statusquerySql.append(" and "+column+" = "+statuscolumnvalue);
				}
				
				String currentdataStr = updRuleMapper.queryOneResultBySql(statusquerySql.toString());
				
				Double currentStatus = Double.parseDouble(currentdataStr);
				Double thresholdData = 0d;
				if("default".equals(updRule.getThresholdtype())) {
					thresholdData = Double.parseDouble(updRule.getStatusthreshold());
				}else if("column".equals(updRule.getThresholdtype())){
					String columnThreshold = updRule.getStatuscolumn();
					Optional<EdiColumnValue> columnThresholdCVC = detailColumnsValue.stream().filter(temp->columnThreshold.equals(temp.getColumnname())).findFirst();;
					thresholdData = Double.parseDouble(columnThresholdCVC.get().getValue()+"");
				}
				
				if(Double.compare(currentStatus, thresholdData) < 0) {
					throw new RuntimeException(updRule.getErrormsg());
				}else {
					String updSql = EdiSqlBuilder.createUpdSqlByColumnValue(detailColumnsValue);
					gatWayHandleDAO.updDynamicCreateSql(updSql);
				}
			}else {
				String updSql = EdiSqlBuilder.createUpdSqlByColumnValue(detailColumnsValue);
				gatWayHandleDAO.updDynamicCreateSql(updSql);
			}

		}
	}
	
	//新增行项
	private void addDetailLine(UpdRule updRule,List<EdiColumnValue> detailColumnsValue,EdiApiDataContext dataContext) {
		EdiColumnValue columnsValue = detailColumnsValue.get(0);
		
		StringBuffer querymaxlineSql = new StringBuffer();
		querymaxlineSql.append("select count(1) from "+columnsValue.getTablename()+" where 1=1");
		String querymaxlinecolumnStr = Optional.ofNullable(updRule.getQuerymaxlinecolumn()).orElse("");
		for(String column:querymaxlinecolumnStr.split(",")) {
			Optional<EdiColumnValue> querymaxlinecolumn = detailColumnsValue.stream().filter(temp->column.equals(temp.getColumnname())).findFirst();;
			String querymaxlinecolumnvalue = "'"+querymaxlinecolumn.get().getValue()+"'";
			querymaxlineSql.append(" and "+column+" = "+querymaxlinecolumnvalue);
		}
		
		String currentLineidStr = dataContext.getApiGlobalMap().get(EdiConstant.EDI_ADD_DETAIL_CURRENT_LINEID)+"";
		if(!StringUtils.hasLength(currentLineidStr) || "null".equals(currentLineidStr)) {
			String maxline =Optional.ofNullable(updRuleMapper.queryOneResultBySql(querymaxlineSql.toString())).orElse("0");
			dataContext.getApiGlobalMap().put(EdiConstant.EDI_ADD_DETAIL_CURRENT_LINEID,maxline);
			currentLineidStr = maxline;
		}
		
		Integer nextlineid = Integer.parseInt(currentLineidStr)+1;
		//设置行号
		Optional<EdiColumnValue>  linenumber =	detailColumnsValue.stream().filter(temp->"true".equals(temp.getIslinenumber())).findFirst();
		linenumber.get().setValue(String.format("%05d", nextlineid));
		dataContext.getApiGlobalMap().put(EdiConstant.EDI_ADD_DETAIL_CURRENT_LINEID,nextlineid+"");
		
		//查询订单号
		Optional<EdiColumnValue>  wmskeyColumn = detailColumnsValue.stream().filter(temp->"true".equals(temp.getIsseriakey())).findFirst();
		
		//拼接查询订单号sql
		StringBuffer originallySql = new StringBuffer();
		originallySql.append("select "+wmskeyColumn.get().getColumnname()+" from "+dataContext.getMainTable().get(0).getTablename()+" where 1=1");
		
		for(String column:updRule.getQueryoriginallywmskeycolumn().split(",")) {
			Optional<EdiColumnValue> queryoriginallywmskeycolumn = detailColumnsValue.stream().filter(temp->column.equals(temp.getColumnname())).findFirst();;
			String queryoriginallywmskeyvalue = "'"+queryoriginallywmskeycolumn.get().getValue()+"'";
			originallySql.append(" and "+column+" = "+queryoriginallywmskeyvalue);
		}
		//原wms单号
		String wmskey =	updRuleMapper.queryOneResultBySql(originallySql.toString());
		wmskeyColumn.get().setValue(wmskey);
		
		//生成新增行项sql
		String inserdetailSql = EdiSqlBuilder.createSqlByColumnValue(detailColumnsValue);
	
		gatWayHandleDAO.saveDynamicCreateSql(inserdetailSql);
	}
	

	@Override
	protected void determineWhseidSaveOrUpdate(EdiApiDataContext dataContext) {
		UpdRule updRule = dataContext.getApiContext().getUpdRule();
		//日志记录配置的更新规则
		dataContext.getEdiLog().getEdiContentLog().setDeterminewhseidsaveorupdatepre(JSON.toJSONString(updRule));
	
		if(updRule == null) {
//			//更新规则不存在,认为执行保存逻辑
			dataContext.getEdiLog().getEdiContentLog().setDeterminewhseidsaveorupdateafter("当前接口未配置数据更新规则！");
			throw new RuntimeException("当前接口未配置数据更新规则！");
		}else {
			//更新规则存在,根据更新规则 组装判断数据是否存在的sql
			String existquerycolumns = updRule.getExistquerycolumns();
			
			//动态组装查询数据sql
			String tempSql = updRule.getExistquerysql();
			existquerycolumns = updRule.getExistquerycolumns();
			for(String columns:existquerycolumns.split(",")) {
				Optional<EdiColumnValue> columnsValue = dataContext.getMainTable().stream().filter(temp->columns.equals(temp.getColumnname())).findFirst();;
				String value = "";
				if(columnsValue.isPresent()) {
					value = columnsValue.get().getValue()+"";
				}
				
				String queryValue = "'"+value+"'";
				String replaceStr = "\\{"+columns+"\\}";
				tempSql = tempSql.replaceAll(replaceStr, queryValue);
			}
			
			//记录拼接是否存在sql
			dataContext.getEdiLog().getEdiContentLog().setDeterminewhseidsaveorupdatequerymainexistssql(tempSql);
			
			String oriDatasourkey = MultipleDataSource.getCurrentDataSourceKey();
			try {
				String datasourcekey =	dataContext.getApiGlobalMap().get(EdiConstant.ACTIVE_MAIN_DATASOURCEKEY)+"";
				MultipleDataSource.setDataSourceKey(datasourcekey);
				int count = updRuleMapper.queryBySql(tempSql);
				if(count == 1 ) {
					
					if("true".equals(updRule.getExistcomparethreshold())) {
						StringBuffer originallySql = new StringBuffer();
						originallySql.append("select "+updRule.getStatuscolumn()+" from "+dataContext.getMainTable().get(0).getTablename()+" where 1=1");
						
						for(String column:updRule.getStatusquerycolumn().split(",")) {
							Optional<EdiColumnValue> statusquerycolumnCVC = dataContext.getMainTable().stream().filter(temp->column.equals(temp.getColumnname())).findFirst();;
							String statusquerycolumnValue = "'"+statusquerycolumnCVC.get().getValue()+"'";
							originallySql.append(" and "+column+" = "+statusquerycolumnValue);
						}
						
						//记录拼接是否需要比较阀值sql
						String status = updRuleMapper.queryOneResultBySql(originallySql.toString());
						int currentStatus = Integer.parseInt(status);
						String statusthresholdStr = updRule.getStatusthreshold();
						int statusthreshold = Integer.parseInt(statusthresholdStr);
						
						if(currentStatus > statusthreshold) {
							
							throw new RuntimeException(updRule.getErrormsg());
						}else {
							dataContext.setDetermineSaveOrUpdate(EdiConstant.ACTIVE_UPDATE);
						}
						
					}else {
						dataContext.setDetermineSaveOrUpdate(EdiConstant.ACTIVE_UPDATE);
					}

				}else if(count < 1){
					dataContext.setDetermineSaveOrUpdate(EdiConstant.ACTIVE_SAVE);
				}else {
					throw new RuntimeException("通过更新规则-"+updRule.getName()+"-判断单据新增或更新异常-接入数据存在多行!");
				}
				MultipleDataSource.ClearDataSourceKey();
				if(null != oriDatasourkey) {
					MultipleDataSource.setDataSourceKey(oriDatasourkey);
				}
			} catch (Exception e) {
				logger.error("",e);
				MultipleDataSource.ClearDataSourceKey();
				if(null != oriDatasourkey) {
					MultipleDataSource.setDataSourceKey(oriDatasourkey);
				}
				throw new RuntimeException("执行更新规则判断异常"+e.getMessage());
			}

		}
	}

}
